package com.tanhua.gateway.filters;

import com.alibaba.fastjson.JSON;
import com.tanhua.commons.utils.JwtUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @auther : 白月尘
 * @date : 14:21  2021/10/27
 */
public class AuthFilter implements GlobalFilter, Ordered {

    @Value("${gateway.excludedUrls}")
    private List<String> excludeUrls;

    /**
     * 核心过滤方法
     * exchange：请求上下文对象（获取request，response）
     * chain：过滤器链
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        //1、判断当前的请求连接，是否需要验证
        String path = request.getURI().getPath();
        if (excludeUrls.contains(path)) {
            //2、如果不需要验证，放行。
            chain.filter(exchange);
        }
        //3、如果需要验证，获取请求头中的 Authorization
        String token = request.getHeaders().get("Authorization").toString();
        if (!StringUtils.isEmpty(token)) {  //针对页面端发送的token前缀 “Bearer ”处理
            token = token.replaceAll("Bearer ", "");
        }
        //4、调用JwtUtils的方法，验证
        boolean b = JwtUtils.verifyToken(token);
        if (b) {
            //5、如果验证通过返回true，放行
            return chain.filter(exchange);
        }
        //6、如果验证失败，响应401并返回
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        Map map = new HashMap();
        map.put("errCode", 401);
        map.put("errMessage", "用户未登录!");
        //设置相应数据格式
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        byte[] bytes = JSON.toJSONBytes(map);
        DataBuffer buffer = response.bufferFactory().wrap(bytes); //数据DatBuffer
        return response.writeWith(Mono.just(buffer));
    }

    /**
     * 配置过滤器的执行顺序
     * 值越大，执行顺序越低
     */
    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}
